import git from 'isomorphic-git'
import FS from '@isomorphic-git/lightning-fs'

// Git文件状态类型
export type GitFileStatus = 'untracked' | 'modified' | 'added' | 'deleted' | 'renamed' | 'clean'

// Git提交信息
export interface GitCommit {
  oid: string
  message: string
  author: {
    name: string
    email: string
    timestamp: number
  }
  committer: {
    name: string
    email: string
    timestamp: number
  }
}

// Git分支信息
export interface GitBranch {
  name: string
  current: boolean
  commit: string
}

// Git文件变更
export interface GitFileChange {
  filepath: string
  status: GitFileStatus
  staged: boolean
}

// Git仓库状态
export interface GitRepoStatus {
  branch: string
  ahead: number
  behind: number
  changes: GitFileChange[]
  hasUncommittedChanges: boolean
}

class GitService {
  private fs: any
  private dir: string = '/workspace'
  private initialized: boolean = false

  constructor() {
    // 初始化文件系统
    this.fs = new FS('GitService')
    
    // 配置isomorphic-git
    git.plugins.set('fs', this.fs)
  }

  // 初始化Git仓库
  async initRepository(projectPath: string = this.dir): Promise<void> {
    try {
      await git.init({
        fs: this.fs,
        dir: projectPath,
        defaultBranch: 'main'
      })
      
      this.dir = projectPath
      this.initialized = true
      
      // 设置默认用户信息
      await this.setUserConfig('用户', 'user@example.com')
      
      console.log('Git仓库初始化成功')
    } catch (error) {
      console.error('Git仓库初始化失败:', error)
      throw new Error('无法初始化Git仓库')
    }
  }

  // 检查是否为Git仓库
  async isRepository(projectPath: string = this.dir): Promise<boolean> {
    try {
      await git.findRoot({
        fs: this.fs,
        filepath: projectPath
      })
      return true
    } catch {
      return false
    }
  }

  // 设置用户配置
  async setUserConfig(name: string, email: string): Promise<void> {
    try {
      await git.setConfig({
        fs: this.fs,
        dir: this.dir,
        path: 'user.name',
        value: name
      })
      
      await git.setConfig({
        fs: this.fs,
        dir: this.dir,
        path: 'user.email',
        value: email
      })
    } catch (error) {
      console.error('设置用户配置失败:', error)
    }
  }

  // 获取仓库状态
  async getStatus(): Promise<GitRepoStatus> {
    if (!this.initialized) {
      throw new Error('Git仓库未初始化')
    }

    try {
      // 获取当前分支
      const branch = await git.currentBranch({
        fs: this.fs,
        dir: this.dir,
        fullname: false
      }) || 'main'

      // 获取文件状态
      const statusMatrix = await git.statusMatrix({
        fs: this.fs,
        dir: this.dir
      })

      const changes: GitFileChange[] = statusMatrix
        .filter(([filepath, , worktreeStatus, stageStatus]) => 
          worktreeStatus !== 1 || stageStatus !== 1
        )
        .map(([filepath, , worktreeStatus, stageStatus]) => ({
          filepath,
          status: this.getFileStatus(worktreeStatus, stageStatus),
          staged: stageStatus !== 1
        }))

      return {
        branch,
        ahead: 0, // 简化实现
        behind: 0, // 简化实现
        changes,
        hasUncommittedChanges: changes.length > 0
      }
    } catch (error) {
      console.error('获取Git状态失败:', error)
      throw new Error('无法获取Git状态')
    }
  }

  // 添加文件到暂存区
  async addFile(filepath: string): Promise<void> {
    try {
      await git.add({
        fs: this.fs,
        dir: this.dir,
        filepath
      })
    } catch (error) {
      console.error('添加文件失败:', error)
      throw new Error(`无法添加文件: ${filepath}`)
    }
  }

  // 添加所有文件到暂存区
  async addAll(): Promise<void> {
    try {
      const statusMatrix = await git.statusMatrix({
        fs: this.fs,
        dir: this.dir
      })

      for (const [filepath, , worktreeStatus] of statusMatrix) {
        if (worktreeStatus !== 1) {
          await this.addFile(filepath)
        }
      }
    } catch (error) {
      console.error('添加所有文件失败:', error)
      throw new Error('无法添加所有文件')
    }
  }

  // 从暂存区移除文件
  async removeFile(filepath: string): Promise<void> {
    try {
      await git.remove({
        fs: this.fs,
        dir: this.dir,
        filepath
      })
    } catch (error) {
      console.error('移除文件失败:', error)
      throw new Error(`无法移除文件: ${filepath}`)
    }
  }

  // 提交更改
  async commit(message: string, author?: { name: string; email: string }): Promise<string> {
    try {
      const oid = await git.commit({
        fs: this.fs,
        dir: this.dir,
        message,
        author: author || {
          name: '用户',
          email: 'user@example.com'
        }
      })
      
      return oid
    } catch (error) {
      console.error('提交失败:', error)
      throw new Error('提交失败，请检查是否有文件在暂存区')
    }
  }

  // 获取提交历史
  async getCommitHistory(limit: number = 20): Promise<GitCommit[]> {
    try {
      const commits = await git.log({
        fs: this.fs,
        dir: this.dir,
        depth: limit
      })

      return commits.map(commit => ({
        oid: commit.oid,
        message: commit.commit.message,
        author: {
          name: commit.commit.author.name,
          email: commit.commit.author.email,
          timestamp: commit.commit.author.timestamp
        },
        committer: {
          name: commit.commit.committer.name,
          email: commit.commit.committer.email,
          timestamp: commit.commit.committer.timestamp
        }
      }))
    } catch (error) {
      console.error('获取提交历史失败:', error)
      return []
    }
  }

  // 获取分支列表
  async getBranches(): Promise<GitBranch[]> {
    try {
      const branches = await git.listBranches({
        fs: this.fs,
        dir: this.dir
      })

      const currentBranch = await git.currentBranch({
        fs: this.fs,
        dir: this.dir,
        fullname: false
      })

      return branches.map(branch => ({
        name: branch,
        current: branch === currentBranch,
        commit: '' // 简化实现
      }))
    } catch (error) {
      console.error('获取分支列表失败:', error)
      return []
    }
  }

  // 创建新分支
  async createBranch(branchName: string): Promise<void> {
    try {
      await git.branch({
        fs: this.fs,
        dir: this.dir,
        ref: branchName
      })
    } catch (error) {
      console.error('创建分支失败:', error)
      throw new Error(`无法创建分支: ${branchName}`)
    }
  }

  // 切换分支
  async checkoutBranch(branchName: string): Promise<void> {
    try {
      await git.checkout({
        fs: this.fs,
        dir: this.dir,
        ref: branchName
      })
    } catch (error) {
      console.error('切换分支失败:', error)
      throw new Error(`无法切换到分支: ${branchName}`)
    }
  }

  // 获取文件差异
  async getDiff(filepath: string): Promise<string> {
    try {
      // 简化实现，实际应该返回详细的diff信息
      const content = await this.fs.promises.readFile(`${this.dir}/${filepath}`, 'utf8')
      return content
    } catch (error) {
      console.error('获取文件差异失败:', error)
      return ''
    }
  }

  // 撤销文件更改
  async discardChanges(filepath: string): Promise<void> {
    try {
      await git.checkout({
        fs: this.fs,
        dir: this.dir,
        ref: 'HEAD',
        filepaths: [filepath]
      })
    } catch (error) {
      console.error('撤销更改失败:', error)
      throw new Error(`无法撤销文件更改: ${filepath}`)
    }
  }

  // 获取文件状态
  private getFileStatus(worktreeStatus: number, stageStatus: number): GitFileStatus {
    if (worktreeStatus === 0 && stageStatus === 0) return 'deleted'
    if (worktreeStatus === 0 && stageStatus === 1) return 'deleted'
    if (worktreeStatus === 1 && stageStatus === 0) return 'added'
    if (worktreeStatus === 1 && stageStatus === 1) return 'clean'
    if (worktreeStatus === 2 && stageStatus === 0) return 'untracked'
    if (worktreeStatus === 2 && stageStatus === 1) return 'modified'
    if (worktreeStatus === 2 && stageStatus === 2) return 'modified'
    return 'modified'
  }

  // 模拟文件系统操作（用于演示）
  async createDemoFiles(): Promise<void> {
    try {
      // 创建示例文件
      await this.fs.promises.writeFile(`${this.dir}/README.md`, `# 我的文档项目

这是一个使用Markdown编辑器创建的项目。

## 功能特性

- 实时预览
- AI智能助手
- Git版本控制
- 跨平台支持

## 开始使用

1. 创建新文档
2. 编写内容
3. 保存并提交到Git
`)

      await this.fs.promises.writeFile(`${this.dir}/docs/介绍.md`, `# 项目介绍

这里是项目的详细介绍...
`)

      console.log('演示文件创建成功')
    } catch (error) {
      console.error('创建演示文件失败:', error)
    }
  }
}

// 导出单例实例
export const gitService = new GitService()

// 导出类型
export type { GitRepoStatus, GitFileChange, GitCommit, GitBranch }